package util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtils {
	private static ServiceRegistry serviceRegistry = null;
	private static Configuration cfg = null;
	private static SessionFactory sessionFactory = null;
	private static Session session = null;

	public static void loadConfig() {
		cfg = new Configuration().configure();
		serviceRegistry = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
		sessionFactory = (SessionFactory) cfg.buildSessionFactory(serviceRegistry);
	}

	public static Session getSession() {
		if (session == null) {
			loadConfig();
			session = sessionFactory.openSession();
		} else if (!session.isOpen()) {
			session = sessionFactory.openSession();
		}
		session.clear();
		return session;
	}

	// hql无参数查询数据
	@SuppressWarnings("rawtypes")
	public static List getByHql(String hql) {
		session = getSession();
		List list = null;
		try {
			Query query = session.createQuery(hql);
			list = query.list();
		} catch (Exception e) {
			System.out.println("查询失败");
			e.printStackTrace();
		}
		return list;
	}

	// hql带参数查询数据
	@SuppressWarnings("rawtypes")
	public static List getByHql(String hql, Object[] param) {
		session = getSession();
		List list = null;
		try {
			Query query = session.createQuery(hql);
			for (int i = 0; i < param.length; i++) {
				query.setParameter(i, param[i]);
			}
			list = query.list();
		} catch (Exception e) {
			System.out.println("查询失败");
			e.printStackTrace();
		}
		return list;
	}

	// hql无参数分页查询数据
	@SuppressWarnings("rawtypes")
	public static List getByHql(String hql, Integer firstIndex, Integer maxSums) {
		session = getSession();
		List list = null;
		try {
			Query query = session.createQuery(hql);
			query.setFirstResult(firstIndex);
			query.setMaxResults(maxSums);
			list = query.list();
		} catch (Exception e) {
			System.out.println("查询失败");
			e.printStackTrace();
		}
		return list;
	}

	// hql带参数分页查询数据
	@SuppressWarnings("rawtypes")
	public static List getByHql(String hql, Object[] param, Integer firstIndex, Integer maxSums) {
		session = getSession();
		List list = null;
		try {
			Query query = session.createQuery(hql);
			for (int i = 0; i < param.length; i++) {
				query.setParameter(i, param[i]);
			}
			query.setFirstResult(firstIndex);
			query.setMaxResults(maxSums);
			list = query.list();
		} catch (Exception e) {
			System.out.println("查询失败");
			e.printStackTrace();
		}
		return list;
	}

	// 相数据表中插入一条数据，需要传入一个对象
	public static <T> boolean addOne(T t) {
		session = getSession();
		boolean flag = false;
		try {
			Transaction transaction = session.beginTransaction();
			session.save(t);
			transaction.commit();
			flag = true;
		} catch (Exception e) {
			session.getTransaction().rollback();
			System.out.println("插入失败");
			e.printStackTrace();
		}
		return flag;
	}

	// 传入一个对象，删除该对象对应的数据
	public static <T> boolean deleteOne(T t) {
		session = getSession();
		try {
			Transaction transaction = session.beginTransaction();
			session.delete(t);
			transaction.commit();
			return true;
		} catch (Exception e) {
			session.getTransaction().rollback();
			System.out.println("删除失败");
			e.printStackTrace();
			return false;
		}
	}

	// 传入class对象和id来获得个对象
	@SuppressWarnings("unchecked")
	public static <T> T getOne(Class<T> c, Object id) {
		session = getSession();
		Criteria criteria = session.createCriteria(c);
		criteria.add((Restrictions.eq("id", id)));
		return (T) criteria.list().get(0);
	}

	public static Object getOne(String hql) {
		return session.createQuery(hql).uniqueResult();
	}
	
	public static Object getOne(String hql, Object[] params) {
		Object object = new Object();
		session = getSession();
		try {
			Query query = session.createQuery(hql);
			for (int i = 0; i < params.length; i++) {
				query.setParameter(i, params[i]);
			}
			object = query.uniqueResult();
		} catch (Exception e) {
			System.out.println("查询失败");
			e.printStackTrace();
		}
		return object;
	}

	// 传入一个class对象来获取到该表中的所有数据
	public static <T> List<T> getAll(Class<T> c) {
		session = getSession();
		Criteria criteria = session.createCriteria(c);
		@SuppressWarnings("unchecked")
		List<T> list = criteria.list();
		return list;
	}

	// 传入一个改变后的对象，更改数据表中的数据
	public static <T> boolean updateOne(T t) {
		session = getSession();
		try {
			Transaction transaction = session.beginTransaction();
			session.update(t);
			transaction.commit();
			return true;
		} catch (Exception e) {
			session.getTransaction().rollback();
			System.out.println("更新失败");
			e.printStackTrace();
			return false;
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static <T> String createQueryHql(T t) {
		StringBuilder hql = new StringBuilder();
		//1.获取到class
		Class c = t.getClass();
		//2.获取到类名
		String className = c.getName();
		className = className.substring(className.lastIndexOf('.') + 1);
		hql.append("from ").append(className).append(" where 1=1");
		//3.遍历所有的字段
		Field[] fArr = c.getDeclaredFields();
		for (Field field : fArr) {
			//4.处理每个字段对应的sql
			//4.1拿到字段名
			String filedName = field.getName();
			//4.2拿到字段的值
			String getMethodName = "get" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
			Object fieldValue = null;
			try {
				Method getMethod = c.getMethod(getMethodName);
				fieldValue = getMethod.invoke(t);
			} catch (Exception e) {
				e.printStackTrace();
			}
			//4.3拼装hql
			if(fieldValue == null || fieldValue.equals("") || (fieldValue instanceof Integer && (Integer) fieldValue == 0)){
				continue;
			} else {
				
			}
			hql.append(" and ").append(filedName);
			if(fieldValue instanceof String){
				if(((String) fieldValue).contains(",")){
					String[] values = ((String) fieldValue).split(",");
					hql.append(" in(");
					for (String value : values) {
						hql.append("'").append(value).append("'").append(",");
					}
					hql.deleteCharAt(hql.length() - 1);
					hql.append(")");
				} else {
					hql.append("=").append("'" + fieldValue + "'");
				}
			} else {
				hql.append("=").append(fieldValue);
			}
		}
		return hql.toString();
	}
	
	// 关闭session
	public static void closeSession() {
		if (session != null) {
			session.close();
			session = null;
		}
	}

}
